package cn.edu.xmu.orderpayment.payment.mq.listener;

import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.orderpayment.payment.Dao.PaymentDao;
import cn.edu.xmu.orderpayment.payment.Dao.PaymentPatternDao;
import cn.edu.xmu.orderpayment.payment.Dao.RefundDao;
import cn.edu.xmu.orderpayment.payment.constants.Constants;
import cn.edu.xmu.orderpayment.payment.model.bo.PaymentPattern;
import cn.edu.xmu.orderpayment.payment.model.bo.Refund;
import cn.edu.xmu.orderpayment.payment.model.po.RefundPo;
import cn.edu.xmu.orderpayment.payment.mq.RocketMQService;
import cn.edu.xmu.orderpayment.payment.mq.obj.AfterSaleMessageBody;
import cn.edu.xmu.orderpayment.payment.util.PayMentPatternLoader;
import cn.edu.xmu.orderpayment.payment.util.baseobject.RefundInfo;
import cn.edu.xmu.orderpayment.payment.util.paypattern.BasePaymentPattern;
import cn.edu.xmu.privilegegateway.annotation.util.JacksonUtil;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

@Service
@RocketMQMessageListener(topic = "refund-check-topic2",  consumeMode = ConsumeMode.CONCURRENTLY, consumeThreadMax = 10, consumerGroup = "refund-check-group2")
public class RefundCheckListener implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {

    private final Logger logger = LoggerFactory.getLogger(RefundCheckListener.class);


    @Autowired
    private PayMentPatternLoader loader;

    @Autowired
    private PaymentDao paymentDao;

    @Autowired
    private RefundDao refundDao;

    @Autowired
    private PaymentPatternDao paymentPatternDao;


    @Autowired
    private RocketMQService rocketMQService;


    // 消费者收到退款检查消息，获得第三方退款信息查看是否已经退款，若已退款则通知售后单或订单
    @Override
    public void onMessage(String json) {

        logger.info(LocalDateTime.now()+"收到退款检查消息，现在去第三方检查退款");

        Refund refund= JacksonUtil.toObj(json,Refund.class);
        Long patternId=refund.getPatternId();
        ReturnObject<PaymentPattern> patternRet=paymentPatternDao.getPaymentPatternById(patternId);

        String className=patternRet.getData().getClassName();

        try {
            // 如果已退款则无操作
            ReturnObject<List<RefundPo>> ret=refundDao.getRefundByDocumentId(refund.getDocumentId());
            if(ret.getData()==null)return;
            List<RefundPo> refundPos = ret.getData();
            Refund refund1 = cloneVo(refundPos.get(0),Refund.class);
            if(refund1.getState()!= Refund.State.PAYMENT_COMPLETED)return;

            // 若第三方已退款，系统未退款，则修改退款
            BasePaymentPattern pattern= loader.getPaymentPatternByClassName(className);

            RequestContextHolder.setRequestAttributes(Constants.servletRequestAttributes);

            RefundInfo refundInfo= pattern.getRefund(refund.getDocumentId(),refund.getId().toString());
            if(refundInfo.getState()== Refund.State.PAYMENT_COMPLETED){
                refund1.setState(Refund.State.PAYMENT_COMPLETED.getCode());
                refund1.setAmount(refundInfo.getAmount());
                refund1.setRefundTime(refundInfo.getSuccessTime());
                refund1.setTradeSn(refundInfo.getTradeSn());
                refundDao.updateRefund(refund1,refund1.getCreatorId(),refund1.getCreatorName());
                if(refund1.getDocumentType()== Refund.DocumentType.AFTERSALE)
                {
                    AfterSaleMessageBody afterSaleMessageBody= new AfterSaleMessageBody(refund1.getDocumentId(),refund1.getAmount());
                    String s=JacksonUtil.toJson(afterSaleMessageBody);
                    rocketMQService.sendSuccessServicePayMessage(s);
                    return;
                }
                if(refund1.getDocumentType()==Refund.DocumentType.NORMAL){
                    rocketMQService.sendSuccessOrderRefundMessage(refund1.getDocumentId());
                    return;
                }

            }
            // 退款失败 修改退款单
            else if(refundInfo.getState()== Refund.State.PAYMENT_FAILED){
                refund1.setState(Refund.State.PAYMENT_FAILED.getCode());
                refund1.setTradeSn(refundInfo.getTradeSn());
                refundDao.updateRefund(refund1,refund1.getCreatorId(),refund1.getCreatorName());
            }

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {

    }
}
